import React, { Component } from 'react'
import './App.css'

let width = 290, height = 290
const delta = 10

export default class App extends Component {

  divRef = React.createRef()
  state = {
    snakehead:
    {
      top: 0,
      left: 0
    },
    snakebody: [
    ],
    score: 0,
    level: 1,
    food: {
      top: 30,
      left: 30
    },
    movest: 'right',
    gamestart: false,
    // timer: null
  }
  newtimer = null

  startgame = () => {
    this.divRef.current.focus();
    this.setState({ gamestart: true })
    // this.foodmove()
    // this.snakeheadmove()
  }

  stopgame=()=>{
    this.divRef.current.focus();
    this.setState({ gamestart: false })
  }

  // componentDidMount() {
  //   width = width
  //   height = height
  // }

  componentDidUpdate(preProps, preState) {
    // let { timer } = this.state
    const { level, gamestart } = this.state
    if ((!preState.gamestart && gamestart) || (preState.level !== level)) {
      clearInterval(this.newtimer)
      const newtimer = setInterval(() => {
        const { movest, snakehead } = this.state
        let newtop
        let newleft
        switch (movest) {
          case 'left': newtop = snakehead.top
            newleft = snakehead.left - delta
            break
          case 'right': newtop = snakehead.top
            newleft = snakehead.left + delta
            break
          case 'up': newtop = snakehead.top - delta
            newleft = snakehead.left
            break
          case 'down': newtop = snakehead.top + delta
            newleft = snakehead.left
            break
          default: newtop = snakehead.top
            newleft = snakehead.left
        }

        if (this.eatfood(newtop, newleft)) {
          this.foodmove();
          this.increasebody(snakehead.top, snakehead.left);
        }
        this.bodymove();
        this.setState({ snakehead: { top: newtop, left: newleft } })
        this.endgame();
      }, level<=10?(340-12*level):(220-5*level))

      this.newtimer = newtimer
      // this.setState({ timer: newtimer })
    }

    if (!gamestart) {
      clearInterval(this.newtimer)
    }
  }

  endgame = () => {
    const { snakehead, snakebody } = this.state
    let status = 0
    if (snakehead.top < 0 || snakehead.top > height || snakehead.left < 0 || snakehead.left > width) {
      alert('撞墙了！！！');
      status = 1
      // clearInterval(newtimer)
      // clearInterval(timer)
      // this.setState({ gamestart: false, movest: 'right', score: 0, level: 0, snakehead: { top: 0, left: 0 }, snakebody: [] })
    }
    for (var j = 0; j <= snakebody.length - 1; j++) {
      if (snakehead.top === snakebody[j].top && snakehead.left === snakebody[j].left) {
        alert('撞到身体了！！！');
        status = 1
        // clearInterval(newtimer)
        // clearInterval(timer)
        // this.setState({ gamestart: false, movest: 'right', score: 0, level: 0, snakehead: { top: 0, left: 0 }, snakebody: [] })
        break;
      }
    }
    if (status) {
      clearInterval(this.newtimer)
      this.setState({ gamestart: false, movest: 'right', score: 0, level: 0, snakehead: { top: 0, left: 0 }, snakebody: [] })
    }
  }

  foodmove = () => {
    // const { snakebody, snakehead } = this.state
    let newtop;
    let newleft;
    do {
      newtop = Math.round(Math.random() * 29) * delta
      newleft = Math.round(Math.random() * 29) * delta
    } while (this.foodinhead(newtop,newleft)||this.foodinbody(newtop,newleft));
    
    this.setState({ food: { top: newtop, left: newleft } })
  }

  foodinhead=(newtop,newleft)=>{
    const {snakehead}=this.state
    if(newtop===snakehead.top&&newleft===snakehead.left){
      return true
    }else{
      return false
    }
  }

  foodinbody=(newtop,newleft)=>{
    const{snakebody}=this.state
    if(snakebody.length===0){
      return false
    }else{
      if(snakebody.find((item)=>{
        return item.top===newtop,item.left===newleft
      })===undefined){
        return false
      }else{
         return true
      }
    }
    
  }

  snakeheadmove = () => {
    const newtop = Math.round(Math.random() * 29) * delta
    const newleft = Math.round(Math.random() * 29) * delta
    this.setState({ snakehead: { top: newtop, left: newleft } })
  }

  eatfood = (top, left) => {
    const { food, score, level } = this.state
    if (top === food.top && left === food.left) {
      const newscore = score + 1;
      this.setState({ score: newscore })
      if (newscore % 5 === 0) {
        const newlevel = level + 1;
        this.setState({ level: newlevel })
      }
      return true
    } else {
      return false
    }
  }

  increasebody = (pretop, preleft) => {
    const { snakebody } = this.state
    const newbody = { top: pretop, left: preleft }
    snakebody.push(newbody)
  }

  bodymove = () => {
    const { snakehead } = this.state
    let { snakebody } = this.state
    // snakebody.push(snakehead)
    // snakebody.shift()
    for (var i = snakebody.length - 1; i >= 0; i--) {
      if (i === 0) {
        snakebody[i].top = snakehead.top;
        snakebody[i].left = snakehead.left;
      } else {
        snakebody[i].top = snakebody[i - 1].top;
        snakebody[i].left = snakebody[i - 1].left;
      }
    }
  }


  handlekeydown = (e) => {
    let { movest,gamestart } = this.state
    let newmovest = movest
    if (e.code === 'ArrowUp' || e.code === 'ArrowDown' || e.code === 'ArrowRight' || e.code === 'ArrowLeft') {
      if ((e.code === 'ArrowUp' && movest === 'down') || (e.code === 'ArrowDown' && movest === 'up') || (e.code === 'ArrowRight' && movest === 'left') || (e.code === 'ArrowLeft' && movest === 'right')) {
        newmovest = movest
      } else {
        switch (e.code) {
          case 'ArrowUp': newmovest = 'up'
            break
          case 'ArrowDown': newmovest = 'down'
            break
          case 'ArrowRight': newmovest = 'right'
            break
          case 'ArrowLeft': newmovest = 'left'
            break
          default: newmovest = movest
        }
      }
    }
    this.setState({ movest: newmovest })
    if(!gamestart&&e.keyCode===13){
      this.startgame();
    }
    if(gamestart&&e.keyCode===13){
      this.stopgame();
    }
  }

  render() {
    let { score, level, snakehead, food, gamestart, snakebody } = this.state
    return (
      <div className="game-box" tabIndex="-1" onKeyDown={(e) => this.handlekeydown(e)} ref={this.divRef}>
        <div className="game-panel">
          <div className="snake" style={{ top: snakehead.top, left: snakehead.left }}></div>
          {snakebody.map((bodyObj, index) => {
            return (<div className="snake" key={index} style={{ top: bodyObj.top, left: bodyObj.left }}></div>)
          })}
          <div className="food" style={{ top: food.top, left: food.left }}></div>
        </div>
        {gamestart ?
          (<div className="score-panel">
            <div>
              <span>SCORE:{score}</span>
            </div>
            <div>
              <span>LEVEL:{level}</span>
            </div>
          </div>)
          :(snakehead.top===0&&snakehead.left===0&&snakebody.length===0 ?(<div className="startgame"><button onClick={this.startgame}>开始游戏</button></div>):
          (<div className="startgame"><button onClick={this.startgame}>继续游戏</button></div>))}
      </div >
    )
  }
}
